﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using DevicesView.Logic.App;
namespace DevicesView.Logic.Oss
{

    public class HuaweiOBS
    {
        private static HuaweiOBS _huaweiobs;

        //private string ossPath = "rc/files/";
        private string ossHost;
        private string bucketName = "rpfield-zlerp";

        private HuaweiOBS()
        {
            //ossServer = "http://rpfield-zlerp.oss-cn-beijing.aliyuncs.com/dev/devices/";
            //ossServer = "http://avatar-zlerp.oss-cn-beijing.aliyuncs.com/dev/devices/";
           
            ossHost = "http://ringpai-phis.obs.cn-north-4.myhuaweicloud.com/";
            bucketName = "ringpai-phis";
            string add= AppResource.CurrentResource.NetConfig.Servers.FirstOrDefault(o => o.ServerName == "XiannuanWebServer")?.Address;
            //测试环境OBS
            if (!add.Contains("124.70.23.220"))
            {
                ossHost = "http://ringpai-dev.obs.cn-north-4.myhuaweicloud.com/";
                bucketName = "ringpai-dev";
            }
        }

        /// <summary>
        /// 创建或获取一个阿里对象存储操作对象
        /// </summary>
        public static HuaweiOBS CreateAliOSS()
        {
            if (_huaweiobs == null)
                _huaweiobs = new HuaweiOBS();
            //FocusServerHttpUtility可能会改变,在使用前重新获取
            //_alioss.foucsHu = HttpUtility.FocusServerHttpUtility;
            //_alioss.ossHU = HttpUtility.CreateUtility(_alioss.CDN, null);
            return _huaweiobs;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public string Put(string filename, Stream sm)
        {
            //string filename = FileLogic.GetFileMD5(sm);
            //string ossName = $"{ossHost}{directoryName}/{filename}";

            //if (OssFileExists(ossName))
            //    return ossName;


            string ossName = $"{ossHost}{filename}";
            HttpItem item = new HttpItem { Url = ossName, Method = HttpMethod.Put };
            item.Content = new byte[sm.Length];
            sm.Position = 0;
            sm.Read(item.Content,0, item.Content.Length);
            item.ContentType = "application/octet-stream";
            DateTime utctime = DateTime.UtcNow;
            item.Date = utctime;
            //item.Headers.Add("Content-MD5: " + ossName);
            item.Headers.Add("x-obs-acl: public-read");
            
            //加密
            Encryption(item, $"/{bucketName}/{filename}");

            HttpResult<string> result = WebLogic.GetHttpResult<string>(item);
            if (result.Success)
                return ossName;
            return null;
        }

        /// <summary>
        /// 获取文件属性
        /// </summary>
        /// <param name="ossPath">相对路径</param>
        /// <returns>如果文件不存在返回null</returns>
        public bool OssFileExists(string ossPath)
        {
            HttpResult<string> result = WebLogic.GetHttpResult<string>(new HttpItem { Method = HttpMethod.Head, Url = ossPath });
            if (result.StatusCode == 404)
                return false;
            return true;
        }



        /// <summary>
        /// 获取签名
        /// </summary>
        /// <returns></returns>
        private string Authorization(string data)
        {
            //本地加密
            //LTAIdhrG7tlfYOUa--- QTeFHiym4l33c5yUu5XWuliMjHmCtX
            //LTAIuQev20xBqmNu---Cr448SaKbcQHebf74znRe5MxFEjzw9
            //return string.Format("OSS {0}:{1}", "LTAIuQev20xBqmNu", ComputeSignatureCore("Cr448SaKbcQHebf74znRe5MxFEjzw9", data));
            return string.Format("OBS {0}:{1}", "OHECMDFOILGX92Z3XDQC", ComputeSignatureCore("OtxQhPAocSx0ZizvXCCMXlWVQ1GVJq2ByPsjBDNd", data));
        }




        /// <summary>
        /// HmacSHA1
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private string ComputeSignatureCore(string key, string data)
        {

            byte[] byteToSign = Encoding.UTF8.GetBytes(data);
            byte[] byteKey = Encoding.UTF8.GetBytes(key);
            HMACSHA1 hmac = new HMACSHA1(byteKey);
            return Convert.ToBase64String(hmac.ComputeHash(byteToSign));

            //using (var algorithm = KeyedHashAlgorithm.Create("HmacSHA1".ToUpperInvariant()))
            //{
            //    algorithm.Key = Encoding.UTF8.GetBytes(key.ToCharArray());
            //    return Convert.ToBase64String(
            //        algorithm.ComputeHash(Encoding.UTF8.GetBytes(data.ToCharArray())));
            //}
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="item"></param>
        /// <param name="ossPath"></param>
        private void Encryption(HttpItem item, string ossPath)
        {
            Dictionary<string, string> headers = item.HeadersToDictionary();
            if (!headers.ContainsKey("Content-MD5"))
                headers.Add("Content-MD5", "");

            string StringToSign = $"{item.Method.ToString().ToUpper()}\n{headers["Content-MD5"]}\n{item.ContentType}\n{item.Date:R}";
            //string StringToSign = $"{item.Method.ToString().ToUpper()}\n\n\n{item.Date:R}";
            foreach (var key in headers.Keys)
                if(key.StartsWith("x-obs-"))
                    StringToSign += $"\n{key.ToLower()}:{headers[key].Trim()}";
            StringToSign += $"\n{ossPath}";

            item.Headers.Add("Authorization: " + Authorization(StringToSign.ToString()));
        }
    }




}
